package com.distributeLock;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.framework.recipes.locks.InterProcessReadWriteLock;
import org.apache.curator.retry.ExponentialBackoffRetry;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.function.Consumer;

public class ZKReadWriteLock {


    public static void main(String[] args) {
        CuratorFramework curatorFramework = CuratorFrameworkFactory.newClient("127.0.0.1:2181", new ExponentialBackoffRetry(1000, 3));

        curatorFramework.start();

        String lockPath = "/zkLockRoot/lock_1";

        InterProcessReadWriteLock lock = new InterProcessReadWriteLock(curatorFramework, lockPath);

        ExecutorService executorService = Executors.newCachedThreadPool();

        Consumer<InterProcessMutex> consumer = (InterProcessMutex typeLock) -> {
            try {
                List<Callable<String>> callableList = new ArrayList<>();

                Callable<String> callable = () -> {
                  try {
                      typeLock.acquire();
                      System.out.println(Thread.currentThread() + " accquire read lock");
                  } catch (Exception e) {

                  } finally {
                      typeLock.release();
                      System.out.println(Thread.currentThread() + " release read lock");
                  }
                  return "true";
                };

                // 5个并发线程
                for (int i =  0; i < 5; i ++) {
                    callableList.add(callable);
                }

                List<Future<String>>  futures = executorService.invokeAll(callableList);
            } catch (Exception e) {

            }
        };

        System.out.println("5个并发线程，读锁测试");

        InterProcessMutex readLock = lock.readLock();
        consumer.accept(readLock);

        //写锁测试（同时只有一个线程获取写锁）
        System.out.println("5个并发线程，写锁测试");
        InterProcessMutex writeLock = lock.writeLock();
        consumer.accept(writeLock);

        executorService.shutdown();

    }

}
